home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / segal / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  41.3 KB  |  1,758 lines

  1. /*
  2.  *    file.c - for use with SEGAL
  3.  *
  4.  *    By Bryan Skene
  5.  *
  6.  *    Uses the complex conversion library by Jin Goujin
  7.  */
  8.  
  9. #include "common.h"
  10. #include "file_ui.h"
  11.  
  12. /*****************************************/
  13. void
  14. load_image_header()
  15. {
  16.     void unload_all_masks();
  17.     void init_info_from_header();
  18.     void update_bytes_required();
  19.  
  20.     char filename[MAXPATHLEN], foo[80];
  21.  
  22.     strcpy(img.dname, (char *) xv_get(File_pop_load_image->text_image_dname, PANEL_VALUE, NULL));
  23.     strcpy(img.fname, (char *) xv_get(File_pop_load_image->text_image_fname, PANEL_VALUE, NULL));
  24.     sprintf(filename, "%s/%s", img.dname, img.fname);
  25.  
  26.     fprintf(stderr, "Loading image: %s\n", filename);
  27.  
  28.     if((img.hd.IN_FP = fopen(filename, "rb")) == NULL) {
  29.         prgmerr(0, "trying to open for input %s", filename);
  30.         return;
  31.     }
  32.  
  33.     format_init(&img.hd, IMAGE_INIT_TYPE, HIPS, HIPS, *av, "Segal v. 3d");
  34.  
  35.     if((*img.hd.header_handle)(HEADER_READ, &img.hd, 0, 0, 0) < 0) {
  36.         prgmerr(0, "Unkown image type");
  37.         return;
  38.     }
  39.  
  40.     /* if color image, we want the data in separate planes */
  41.     img.hd.color_form = CFM_SEPLANE;
  42.  
  43.     (*img.hd.header_handle)(HEADER_TRANSF, &img.hd, 0);
  44.  
  45.     unload_all_masks(FALSE);
  46.     init_info_from_header();
  47.  
  48.     /* set up the ui stuff */
  49.     sprintf(foo, "Image format: %s (%3dR x %3dC x %3dF)",
  50.         ITypeName[img.hd.in_type], img.r, img.c, img.f);
  51.     xv_set(File_pop_load_image->msg_format,
  52.         PANEL_LABEL_STRING, foo,
  53.         PANEL_INACTIVE, FALSE,
  54.         NULL);
  55.  
  56.     xv_set(File_pop_load_image->msg_bytes_required,
  57.         PANEL_INACTIVE, FALSE,
  58.         NULL);
  59.  
  60.     xv_set(File_pop_load_image->row_from,
  61.         PANEL_MIN_VALUE, 0,
  62.         PANEL_MAX_VALUE, img.r - 1,
  63.         PANEL_VALUE, segal.r1,
  64.         PANEL_INACTIVE, FALSE,
  65.         NULL);
  66.  
  67.     xv_set(File_pop_load_image->row_to,
  68.         PANEL_MIN_VALUE, 0,
  69.         PANEL_MAX_VALUE, img.r - 1,
  70.         PANEL_VALUE, segal.r2,
  71.         PANEL_INACTIVE, FALSE,
  72.         NULL);
  73.  
  74.     xv_set(File_pop_load_image->col_from,
  75.         PANEL_MIN_VALUE, 0,
  76.         PANEL_MAX_VALUE, img.c - 1,
  77.         PANEL_VALUE, segal.c1,
  78.         PANEL_INACTIVE, FALSE,
  79.         NULL);
  80.  
  81.     xv_set(File_pop_load_image->col_to,
  82.         PANEL_MIN_VALUE, 0,
  83.         PANEL_MAX_VALUE, img.c - 1,
  84.         PANEL_VALUE, segal.c2,
  85.         PANEL_INACTIVE, FALSE,
  86.         NULL);
  87.  
  88.  
  89.     xv_set(File_pop_load_image->frm_from,
  90.         PANEL_MIN_VALUE, 0,
  91.         PANEL_MAX_VALUE, img.f - 1,
  92.         PANEL_VALUE, segal.f1,
  93.         PANEL_INACTIVE, !segal.r3d,
  94.         NULL);
  95.  
  96.     xv_set(File_pop_load_image->frm_to,
  97.         PANEL_MIN_VALUE, 0,
  98.         PANEL_MAX_VALUE, img.f - 1,
  99.         PANEL_VALUE, segal.f2,
  100.         PANEL_INACTIVE, !segal.r3d,
  101.         NULL);
  102.  
  103.     xv_set(File_pop_load_image->set_color_format,
  104.         PANEL_VALUE, (img.color ? 0 : 1),
  105.         PANEL_INACTIVE, !img.color,
  106.         NULL);
  107.     
  108.     /* (de)activate other color stuff */
  109.     xv_set(Preferences_pop_preferences_display->msg_quantizing,
  110.         PANEL_INACTIVE, !img.color,
  111.         NULL);
  112.  
  113.     xv_set(Preferences_pop_preferences_display->set_requant_win,
  114.         PANEL_INACTIVE, !img.color,
  115.         NULL);
  116.  
  117.     xv_set(Preferences_pop_preferences_display->set_requant_quality,
  118.         PANEL_INACTIVE, !img.color,
  119.         NULL);
  120.  
  121.     xv_set(Preferences_pop_preferences_display->but_requant,
  122.         PANEL_INACTIVE, !img.color,
  123.         NULL);
  124.  
  125.     xv_set(Threshold_pop_threshold->set_plane,
  126.         PANEL_INACTIVE, !img.color,
  127.         NULL);
  128.  
  129.     update_bytes_required();
  130.  
  131.     /* now that we have a valid image, allow loading */
  132.     xv_set(File_pop_load_image->but_load_image,
  133.         PANEL_INACTIVE, FALSE,
  134.         NULL);
  135. }
  136.  
  137. /*****************************************/
  138. void
  139. load_image()
  140. {
  141.     void init_info_from_loading();
  142.     void view_setup();
  143.     void paint_setup();
  144.     void allocate_buffers();
  145.     LOGIC begin_timer();
  146.     void enq_bg_job();
  147.     void begin_itimer();
  148.     Notify_value bg_load_image_frame();
  149.  
  150.     init_info_from_loading();
  151.  
  152.     view_setup();
  153.     paint_setup();
  154.  
  155.     allocate_buffers();
  156.  
  157.     /* prepare to load frames beginning with segal.f1 ... */
  158.     img.hd.load_all = 1;
  159.     vprint"img.frame_size = %d, img.hd.channels = %d\n",
  160.         img.frame_size, img.hd.channels);
  161.     img.hd.data = Calloc(img.frame_size * img.hd.channels, byte);
  162.  
  163.     /*** Load all the frames ***/
  164.  
  165.     /* gonna do something time intensive ... background it */
  166.     sprintf(timer.message, "Loading frames: %s ...", img.fname);
  167.     if(!begin_timer()) enq_bg_job(JOB_LOAD_IMAGE, 0);
  168.     else {
  169.         segal.bg_i = segal.f1;
  170.         begin_itimer(INTERVAL_SEC, INTERVAL_uSEC);
  171.         notify_set_itimer_func(File_pop_load_image->pop_load_image,
  172.             bg_load_image_frame, ITIMER_REAL, &itimer, NULL);
  173.     }
  174. }
  175.  
  176. /*****************************************/
  177. Notify_value
  178. bg_load_image_frame()
  179. {
  180.     void set_timer();
  181.     void deq_bg_job();
  182.     void end_timer();
  183.     void get_2d_slice();
  184.     void get_quant_colors();
  185.     void cmap_init();
  186.     void FreeAllColors();
  187.     void build_cmap();
  188.     void redisplay_all();
  189.     void save_image_undo();
  190.     void save_image_orig();
  191.  
  192.     int x, y, i, size;
  193.     long offset;
  194.     char filename[MAXPATHLEN];
  195.  
  196.     if(segal.bg_i <= segal.f2) {
  197.         img.hd.fn = segal.bg_i;
  198.         (*img.hd.std_swif)(FI_ACCESS_ABS_FRAME, &img.hd, img.hd.data, img.hd.fn);
  199.  
  200.         if(segal.color) { /* extract the RGB planes from hd.data */
  201.             size = segal.r * segal.c;
  202.  
  203.             if(segal.c == img.c) {
  204.             /* unless the #columns change, can extract fast */
  205.                 For_rgb bcopy(
  206.                 &img.hd.data[i * size + segal.r1 * img.c],
  207.                     cbuf[i][segal.bg_i - segal.f1][0],
  208.                     segal.r * segal.c);
  209.             }
  210.             else { /* gotta do it the hard way */
  211.                 For_rgb
  212.                 for(y = 0; y < segal.r; y++)
  213.                 for(x = 0; x < segal.c; x++)
  214.                     cbuf[i][segal.bg_i - segal.f1][y][x]
  215.                     = img.hd.data[(int) (i*size + x+segal.c1 + ((y+segal.r1) * img.c))];
  216.             }
  217.         }
  218.         else {
  219.             if(segal.c == img.c) {
  220.             /* unless the #columns change, can extract fast */
  221.                 bcopy(&img.hd.data[segal.r1 * img.c],
  222.                     ibuf[segal.bg_i - segal.f1][0],
  223.                     segal.r * segal.c);
  224.             }
  225.             else { /* gotta do it the hard way */
  226.                 for(y = 0; y < segal.r; y++)
  227.                 for(x = 0; x < segal.c; x++)
  228.                     ibuf[segal.bg_i - segal.f1][y][x]
  229.                         = img.hd.data[(int) (x+segal.c1
  230.                         + ((y+segal.r1) * img.c))];
  231.             }
  232.         }
  233.  
  234.         segal.bg_i++;
  235.  
  236.         set_timer((float) (segal.bg_i - segal.f1) / (float) segal.f);
  237.     }
  238.     else {
  239.     /* Done loading image */
  240.     /*    fclose(img.hd.IN_FP);    */
  241.         img.loaded = TRUE;
  242.         For_all_windows win[i].f = 0;
  243.  
  244.         /* allocate colors to fit existing colormap */
  245.         image_map = (byte *) malloc(win[WIN_VZ].img_size);
  246.         if(segal.color) {
  247.             For_rgb get_2d_slice(ASPECT_Z, 0, cbuf[i],
  248.                 win[WIN_VZ].i_data[i]);
  249.  
  250.             vprint"*** Getting Quant Colors\n");
  251.             get_quant_colors(win[WIN_VZ].i_data, win[WIN_VZ].img_r,
  252.                 win[WIN_VZ].img_c);
  253.         }
  254.         else get_2d_slice(ASPECT_Z, 0, ibuf, win[WIN_VZ].i_data[GRAY]);
  255.         cmap_init();
  256.         FreeAllColors();
  257.         build_cmap();
  258.  
  259.         redisplay_all();
  260.  
  261.         save_image_undo(WIN_PAINT);
  262.         save_image_orig(WIN_PAINT);
  263.  
  264.         free(img.hd.data);
  265.         img.hd.data = NULL;
  266.  
  267.         sprintf(filename, "Image: %s (%dr x %dc x %df)",
  268.             img.fname, segal.r, segal.c, segal.f);
  269.         xv_set(View_win->msg_image,
  270.             PANEL_LABEL_STRING, filename,
  271.             NULL);
  272.  
  273.         xv_set(File_pop_load_image->pop_load_image,
  274.             XV_SHOW, FALSE,
  275.             NULL);
  276.  
  277.         xv_set(View_win->set_display,
  278.             PANEL_INACTIVE, FALSE,
  279.             NULL);
  280.  
  281.         xv_set(View_win->but_masks,
  282.             PANEL_INACTIVE, FALSE,
  283.             NULL);
  284.  
  285.         xv_set(View_win->but_preferences,
  286.             PANEL_INACTIVE, FALSE,
  287.             NULL);
  288.  
  289.         end_timer();
  290.  
  291.         notify_set_itimer_func(File_pop_load_image->pop_load_image,
  292.             NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL);
  293.  
  294.         deq_bg_job();
  295.  
  296.         return NOTIFY_DONE;
  297.     }
  298. }
  299.  
  300. /*****************************************/
  301. void
  302. save_image_as()
  303. {
  304.     void save_image();
  305.  
  306.     char filename[MAXPATHLEN];
  307.  
  308.     strcpy(img.dname, (char *) xv_get(File_pop_save_image->text_i_save_dname,
  309.         PANEL_VALUE, NULL));
  310.     strcpy(img.fname, (char *) xv_get(File_pop_save_image->text_i_save_fname,
  311.         PANEL_VALUE, NULL));
  312.     sprintf(filename, "%s/%s", img.dname, img.fname);
  313.     img.hd.name = str_save(filename);
  314.  
  315.     /* TRUE -> save image even if not saved */
  316.     save_image(TRUE);
  317.  
  318.     xv_set(File_pop_save_image->pop_save_image,
  319.         XV_SHOW, FALSE,
  320.         NULL);
  321. }
  322.  
  323. /*****************************************/
  324. LOGIC
  325. overwrite_image(notice_msg)
  326. char *notice_msg;
  327. {
  328.     int but_x, but_y, result;
  329.  
  330.     but_x = (unsigned short) xv_get(View_win->but_image, XV_X, NULL)
  331.         + (unsigned short) xv_get(View_win->win, XV_X, NULL);
  332.     but_y = (unsigned short) xv_get(View_win->but_image, XV_Y, NULL)
  333.         + (unsigned short) xv_get(View_win->win, XV_Y, NULL);
  334.     result = notice_prompt(View_win->win, NULL,
  335.         NOTICE_FOCUS_XY, but_x, but_y,
  336.         NOTICE_MESSAGE_STRINGS, notice_msg,
  337.             "Saving will overwrite the image.",
  338.             NULL,
  339.         NOTICE_BUTTON_YES, "Save image",
  340.         NOTICE_BUTTON_NO, "Cancel",
  341.         NULL);
  342.     if(result == NOTICE_NO) return FALSE;
  343.     else return TRUE;
  344. }
  345.  
  346. /*****************************************/
  347. void
  348. save_image(save_explicit)
  349. LOGIC save_explicit;
  350. {
  351.     LOGIC overwrite_image();
  352.     Notify_value bg_save_image_frame();
  353.  
  354.     char foo[80];
  355.  
  356.     if(img.changed_image) {
  357.         sprintf(foo, "The image %s has been altered but not saved.",
  358.             img.fname);
  359.         overwrite_image(foo);
  360.     }
  361.     else if(!save_explicit) return;
  362.  
  363.     vprint"Save image %s\n", img.fname);
  364.     if((img.hd.OUT_FP = fopen(img.hd.name, "w")) == NULL) {
  365.         prgmerr(0, "Can't open %s for saving!!", img.fname);
  366.         return;
  367.     }
  368.     if((*img.hd.header_handle)(HEADER_WRITE, &img.hd,
  369.         ac, av, img.changed_image) < 0) {
  370.         prgmerr(0, "Unkown image type");
  371.         return;
  372.     }
  373.  
  374.     /*** Save all the frames ***/
  375.  
  376.     /* gonna do something time intensive ... background it */
  377.     sprintf(timer.message, "Saving frames: %s ...", img.fname);
  378.     if(!begin_timer()) enq_bg_job(JOB_SAVE_IMAGE, 0);
  379.     else {
  380.         segal.bg_i = 0;
  381.         begin_itimer(INTERVAL_SEC, INTERVAL_uSEC);
  382.         notify_set_itimer_func(File_pop_load_image->pop_load_image,
  383.             bg_save_image_frame, ITIMER_REAL, &itimer, NULL);
  384.     }
  385. }
  386.  
  387. /*****************************************/
  388. Notify_value
  389. bg_save_image_frame()
  390. {
  391.     void set_timer();
  392.     void deq_bg_job();
  393.     void end_timer();
  394.  
  395.     if(segal.bg_i < segal.f) {
  396.         (*img.hd.std_swif)(FI_SAVE_FILE, &img.hd, ibuf[segal.bg_i][0], 0);
  397.         segal.bg_i++;
  398.  
  399.         set_timer((float) segal.bg_i / (float) segal.f);
  400.     }
  401.     else {
  402.         img.changed_image = FALSE;
  403.  
  404.         end_timer();
  405.  
  406.         notify_set_itimer_func(File_pop_load_image->pop_load_image,
  407.             NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL);
  408.  
  409.         deq_bg_job();
  410.  
  411.         return NOTIFY_DONE;
  412.     }
  413. }
  414.  
  415. /*****************************************/
  416. void
  417. load_list()
  418. {
  419.     void load_image_header();
  420.     void load_image();
  421.     void load_mask_proc();
  422.     char *get_non_comment();
  423.  
  424.     char dname[MAXPATHLEN], fname[MAXPATHLEN], filename[MAXPATHLEN];
  425.  
  426.     strcpy(filename, (char *) xv_get(List_pop_list->text_l_fname,
  427.         PANEL_VALUE, NULL));
  428.     vprint"Loading from list %s\n", filename);
  429.  
  430.     /* First, the image path */
  431.     strcpy(dname, (char *) xv_get(List_pop_list->text_i_dname,
  432.         PANEL_VALUE, NULL));
  433.     xv_set(File_pop_load_image->text_image_dname,
  434.         PANEL_VALUE, dname,
  435.         NULL);
  436.  
  437.     /* Second, the image */
  438.     strcpy(fname, (char *) xv_get(List_pop_list->text_i_fname,
  439.         PANEL_VALUE, NULL));
  440.     xv_set(File_pop_load_image->text_image_fname,
  441.         PANEL_VALUE, fname,
  442.         NULL);
  443.     load_image_header();
  444.     load_image();
  445.  
  446.     /* Third, the masks path */
  447.     if(strcmp(strcpy(dname, (char *) xv_get(List_pop_list->text_m_dname,
  448.         PANEL_VALUE,NULL)), "<None>") != 0) {
  449.         xv_set(File_pop_load_mask->text_mask_dname,
  450.             PANEL_VALUE, dname,
  451.             NULL);
  452.     }
  453.  
  454.     /* Fourth, the masks */
  455.     if(strcmp(strcpy(fname, (char *) xv_get(List_pop_list->text_m1_fname,
  456.         PANEL_VALUE,NULL)), "<None>") != 0) {
  457.         xv_set(File_pop_load_mask->text_mask_fname,
  458.             PANEL_VALUE, fname,
  459.             NULL);
  460.         load_mask_proc();
  461.     }
  462.     if(strcmp(strcpy(fname, (char *) xv_get(List_pop_list->text_m2_fname,
  463.         PANEL_VALUE,NULL)), "<None>") != 0) {
  464.         xv_set(File_pop_load_mask->text_mask_fname,
  465.             PANEL_VALUE, fname,
  466.             NULL);
  467.         load_mask_proc();
  468.     }
  469.     if(strcmp(strcpy(fname, (char *) xv_get(List_pop_list->text_m3_fname,
  470.         PANEL_VALUE,NULL)), "<None>") != 0) {
  471.         xv_set(File_pop_load_mask->text_mask_fname,
  472.             PANEL_VALUE, fname,
  473.             NULL);
  474.         load_mask_proc();
  475.     }
  476.     if(strcmp(strcpy(fname, (char *) xv_get(List_pop_list->text_m4_fname,
  477.         PANEL_VALUE,NULL)), "<None>") != 0) {
  478.         xv_set(File_pop_load_mask->text_mask_fname,
  479.             PANEL_VALUE, fname,
  480.             NULL);
  481.         load_mask_proc();
  482.     }
  483.     if(strcmp(strcpy(fname, (char *) xv_get(List_pop_list->text_m5_fname,
  484.         PANEL_VALUE,NULL)), "<None>") != 0) {
  485.         xv_set(File_pop_load_mask->text_mask_fname,
  486.             PANEL_VALUE, fname,
  487.             NULL);
  488.         load_mask_proc();
  489.     }
  490.  
  491.     /* close the load list window */
  492.     xv_set(List_pop_list->pop_list,
  493.         XV_SHOW, FALSE,
  494.         NULL);
  495. }
  496.  
  497. /*****************************************/
  498. LOGIC
  499. create_new_mask(notice_msg)
  500. char *notice_msg;
  501. {
  502.     int but_x, but_y, result;
  503.  
  504.     but_x = (unsigned short) xv_get(View_win->but_image, XV_X, NULL)
  505.         + (unsigned short) xv_get(View_win->win, XV_X, NULL);
  506.     but_y = (unsigned short) xv_get(View_win->but_image, XV_Y, NULL)
  507.         + (unsigned short) xv_get(View_win->win, XV_Y, NULL);
  508.     result = notice_prompt(View_win->win, NULL,
  509.         NOTICE_FOCUS_XY, but_x, but_y,
  510.         NOTICE_MESSAGE_STRINGS, notice_msg,
  511.             "Go ahead and create it?",
  512.             NULL,
  513.         NOTICE_BUTTON_YES, "Yes",
  514.         NOTICE_BUTTON_NO, "No",
  515.         NULL);
  516.     if(result == NOTICE_NO) return FALSE;
  517.     else return TRUE;
  518. }
  519.  
  520. /*****************************************/
  521. void
  522. load_mask_proc()
  523. {
  524.     LOGIC create_new_mask();
  525.     void new_mask_proc();
  526.     LOGIC begin_timer();
  527.     void enq_bg_job();
  528.     void begin_itimer();
  529.     Notify_value bg_load_mask_frame();
  530.  
  531.     char filename[MAXPATHLEN], foo[120];
  532.     int new, i;
  533.  
  534.     /* check for max limit of masks */
  535.     if(segal.num_m == MAX_MASKS) {
  536.         vprint"Mask limit (%d) has been reached.  Please remove one first.\n", MAX_MASKS);
  537.         return;
  538.     }
  539.  
  540.     /* setup space for a new mask */
  541.     segal.new_m  = new = segal.num_m;
  542.     strcpy(m[new].dname, (char *) xv_get(File_pop_load_mask->text_mask_dname, PANEL_VALUE, NULL));
  543.     strcpy(m[new].fname, (char *) xv_get(File_pop_load_mask->text_mask_fname, PANEL_VALUE, NULL));
  544.     sprintf(filename, "%s/%s", m[new].dname, m[new].fname);
  545.     m[new].hd.name = str_save(filename);
  546.  
  547.     /* no duplicate mask names allowed in log */
  548.     for(i = 0; i < segal.num_m; i++)
  549.         if(strcmp(m[i].fname, m[new].fname) == 0) {
  550.             vprint"The mask %s is already in the Mask Log.\n", m[new].fname);
  551.             return;
  552.         }
  553.  
  554.     fprintf(stderr, "Loading mask: %s\n", filename);
  555.  
  556.     if((m[new].hd.IN_FP = fopen(filename, "rw")) == NULL) {
  557.         /* No mask was found - create a new one? */
  558.         sprintf(foo, "The mask %s was not found or couldn't be loaded.",
  559.             m[new].fname);
  560.         if(create_new_mask(foo)) {
  561.             xv_set(File_pop_new_mask->text_new_dname,
  562.                 PANEL_VALUE, m[new].dname,
  563.                 NULL);
  564.             xv_set(File_pop_new_mask->text_new_fname,
  565.                 PANEL_VALUE, m[new].fname,
  566.                 NULL);
  567.             new_mask_proc();
  568.         }
  569.         return;
  570.     }
  571.  
  572.     format_init(&m[new].hd, IMAGE_INIT_TYPE, HIPS, HIPS, *av, "Segal v. 3d");
  573.  
  574.     if((*m[new].hd.header_handle)(HEADER_READ, &m[new].hd, 0, 0, 0) < 0) {
  575.         prgmerr(0, "Unkown image type");
  576.         return;
  577.     }
  578.  
  579.     (*m[new].hd.header_handle)(HEADER_TRANSF, &m[new].hd, 0);
  580.  
  581.     xv_set(File_pop_load_mask->pop_load_mask,
  582.         XV_SHOW, FALSE,
  583.         NULL);
  584.  
  585.     /*** Load all the frames ***/
  586.  
  587.     /* gonna do something time intensive ... background it */
  588.     sprintf(timer.message, "Loading frames: %s ...", m[new].fname);
  589.     if(!begin_timer()) enq_bg_job(JOB_LOAD_MASK, new);
  590.     else {
  591.         m[new].f = 0;
  592.         begin_itimer(INTERVAL_SEC, INTERVAL_uSEC);
  593.         notify_set_itimer_func(File_pop_load_mask->pop_load_mask,
  594.             bg_load_mask_frame, ITIMER_REAL, &itimer, NULL);
  595.     }
  596.  
  597.     segal.num_m++;
  598. }
  599.  
  600. /*****************************************/
  601. Notify_value
  602. bg_load_mask_frame()
  603. {
  604.     void store_byte_to_bit();
  605.     void set_timer();
  606.     void deq_bg_job();
  607.     void redisplay_all();
  608.     void add_to_mask_log();
  609.  
  610.     /* recall ... new = segal.new_m at this point */
  611.  
  612.     if(m[segal.new_m].f < segal.f) {
  613.         (*m[segal.new_m].hd.std_swif)(FI_LOAD_FILE, &m[segal.new_m].hd, 0, 0);
  614.  
  615.         /* pack the bytes to the appropriate bit in mbuf */
  616.         store_byte_to_bit(m[segal.new_m].hd.data, mbuf[m[segal.new_m].f][0], segal.r * segal.c, segal.new_m);
  617.  
  618.         m[segal.new_m].f++;
  619.         set_timer((float) m[segal.new_m].f / (float) segal.f);
  620.     }
  621.     else {
  622.         free(m[segal.new_m].hd.data);
  623.         m[segal.new_m].hd.data = NULL;
  624.         fclose(m[segal.new_m].hd.IN_FP);
  625.  
  626.         m[segal.new_m].loaded = TRUE;
  627.         if(segal.new_m == 0 && segal.disp_mask) {
  628.             segal.e_m = 0;
  629.             redisplay_all(); 
  630.         }
  631.  
  632.         /* add mask filename to mask log */
  633.         add_to_mask_log(segal.new_m);
  634.  
  635.         xv_set(File_pop_load_mask->pop_load_mask,
  636.             XV_SHOW, FALSE,
  637.             NULL);
  638.  
  639.         end_timer();
  640.  
  641.         notify_set_itimer_func(File_pop_load_mask->pop_load_mask,
  642.             NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL);
  643.  
  644.         deq_bg_job();
  645.  
  646.         return NOTIFY_DONE;
  647.     }
  648. }
  649.  
  650. /*****************************************/
  651. void
  652. unload_mask(redisplay)
  653. LOGIC redisplay;
  654. {
  655.     void save_mask();
  656.     void copy_mask();
  657.     void copy_mask_info();
  658.     char *mask_list_string();
  659.     void redisplay_all();
  660.  
  661.     LOGIC edit_mask_changed;
  662.     int but_x, but_y, result;
  663.     char foo[80];
  664.  
  665.     if(mlog.sel_m == UNDEFINED)
  666.         prgmerr(0, "please select a mask to unload");
  667.     vprint"Unload mask %s\n", m[mlog.sel_m].fname);
  668.  
  669.     /* if mask has not been saved after editing, pop up a warning */
  670.     if(m[mlog.sel_m].changed_mask) {
  671.         but_x = (unsigned short) xv_get(
  672.             View_win->win, XV_X, NULL);
  673.         but_y = (unsigned short) xv_get(
  674.             View_win->win, XV_Y, NULL);
  675.         sprintf(foo, "The mask %s has not been saved.",
  676.             m[mlog.sel_m].fname);
  677.         result = notice_prompt(View_win->win, NULL,
  678.             NOTICE_FOCUS_XY, but_x, but_y,
  679.             NOTICE_MESSAGE_STRINGS, foo, NULL,
  680.             NOTICE_BUTTON_YES, "Save mask",
  681.             NOTICE_BUTTON_NO, "Continue unloading",
  682.             NULL);
  683.         if(result == NOTICE_YES) save_mask();
  684.     }
  685.  
  686.     strcpy(m[mlog.sel_m].fname, "<None>");
  687.  
  688.     if(mlog.sel_m == segal.e_m) edit_mask_changed = TRUE;
  689.     else edit_mask_changed = FALSE;
  690.  
  691.     if(mlog.sel_m == segal.num_m - 1) {
  692.         xv_set(Mask_log_pop_mask_log->ls_mask_filenames,
  693.             PANEL_LIST_DELETE, segal.num_m - 1,
  694.             NULL);
  695.     }
  696.     else {
  697.         copy_mask(mbuf[0][0], mbuf[0][0], m[segal.num_m - 1].bit_key, m[mlog.sel_m].bit_key, segal.r * segal.c * segal.f);
  698.         copy_mask_info(segal.num_m - 1, mlog.sel_m);
  699.         xv_set(Mask_log_pop_mask_log->ls_mask_filenames,
  700.             PANEL_LIST_STRING, mlog.sel_m,
  701.                 mask_list_string(mlog.sel_m),
  702.             PANEL_LIST_DELETE, segal.num_m - 1,
  703.             NULL);
  704.     }
  705.     segal.num_m--;    
  706.     sprintf(foo, "Masks Loaded: %3d", segal.num_m);
  707.     xv_set(Mask_log_pop_mask_log->msg_masks_loaded,
  708.         PANEL_LABEL_STRING, foo,
  709.         NULL);
  710.     if(segal.num_m == 0
  711.     || edit_mask_changed) {
  712.         segal.e_m = UNDEFINED;
  713.         if(redisplay) redisplay_all();
  714.     }
  715. }
  716.  
  717. /*****************************************/
  718. void
  719. unload_all_masks(redisplay)
  720. LOGIC redisplay;
  721. {
  722.     void unload_mask();
  723.  
  724.     while(segal.num_m != 0) {
  725.         mlog.sel_m = segal.num_m - 1;
  726.         unload_mask(redisplay);
  727.     }
  728. }
  729.  
  730. /*****************************************/
  731. void
  732. save_mask_as()
  733. {
  734.     char *mask_list_string();
  735.     void save_mask();
  736.  
  737.     strcpy(m[mlog.sel_m].dname, (char *) xv_get(File_pop_save_as->text_save_dname, PANEL_VALUE, NULL));
  738.     strcpy(m[mlog.sel_m].fname, (char *) xv_get(File_pop_save_as->text_save_fname, PANEL_VALUE, NULL));
  739.     sprintf(m[mlog.sel_m].hd.name, "%s/%s", m[mlog.sel_m].dname, m[mlog.sel_m].fname);
  740.  
  741.     /* change the name in the list */
  742.     xv_set(Mask_log_pop_mask_log->ls_mask_filenames,
  743.         PANEL_LIST_STRING, mlog.sel_m, mask_list_string(mlog.sel_m),
  744.         NULL);
  745.  
  746.     save_mask();
  747.  
  748.     xv_set(File_pop_save_as->pop_save_as,
  749.         XV_SHOW, FALSE,
  750.         NULL);
  751. }
  752.  
  753. /*****************************************/
  754. void
  755. save_mask()
  756. {
  757.     Notify_value bg_save_mask_frame();
  758.  
  759.     extern    debug;
  760.  
  761.     vprint"Saving mask: %s\n", m[mlog.sel_m].hd.name);
  762.  
  763.     if((m[mlog.sel_m].hd.OUT_FP = fopen(m[mlog.sel_m].hd.name, "w"))
  764.         == NULL) {
  765.         prgmerr(0, "Can't open %s for saving!!", m[mlog.sel_m].fname);
  766.         return;
  767.     }
  768.  
  769.     if((*m[mlog.sel_m].hd.header_handle)(HEADER_WRITE, &m[mlog.sel_m].hd,
  770.         ac, av, TRUE) < 0) {
  771.         prgmerr(0, "Unkown image type");
  772.         return;
  773.     }
  774.  
  775.     /*** Save all the frames ***/
  776.  
  777.     /* gonna do something time intensive ... background it */
  778.     sprintf(timer.message, "Saving frames: %s ...", m[mlog.sel_m].fname);
  779.     if(!begin_timer()) enq_bg_job(JOB_SAVE_MASK, mlog.sel_m);
  780.     else {
  781.         segal.new_m = mlog.sel_m;
  782.         m[mlog.sel_m].f = 0;
  783.         begin_itimer(INTERVAL_SEC, INTERVAL_uSEC);
  784.         notify_set_itimer_func(File_pop_load_mask->pop_load_mask,
  785.             bg_save_mask_frame, ITIMER_REAL, &itimer, NULL);
  786.     }
  787. }
  788.  
  789. /*****************************************/
  790. Notify_value
  791. bg_save_mask_frame()
  792. {
  793.     void get_2d_slice();
  794.     void set_timer();
  795.     void end_timer();
  796.     void deq_bg_job();
  797.  
  798.     int i;
  799.  
  800.     /* we use th view z mask buffer ... */
  801.  
  802.     if(m[segal.new_m].f < segal.f) {
  803.         get_2d_slice(ASPECT_Z, m[segal.new_m].f, mbuf, &win[WIN_VZ].m_data[0]);
  804.         for(i = 0; i < segal.r * segal.c; i++)
  805.             if(BIT_IS_ON(win[WIN_VZ].m_data[0][i], m[segal.new_m].bit_key))
  806.                 win[WIN_VZ].m_data[0][i] = 255;
  807.             else win[WIN_VZ].m_data[0][i] = FALSE;
  808.  
  809.         (*m[segal.new_m].hd.std_swif)(FI_SAVE_FILE, &m[segal.new_m].hd,
  810.             win[WIN_VZ].m_data[0], 0);
  811.  
  812.         m[segal.new_m].f++;
  813.         set_timer((float) m[segal.new_m].f / (float) segal.f);
  814.     }
  815.     else {
  816.         fclose(m[segal.new_m].hd.OUT_FP);
  817.         m[segal.new_m].changed_mask = FALSE;
  818.  
  819.         end_timer();
  820.  
  821.         notify_set_itimer_func(File_pop_load_mask->pop_load_mask,
  822.             NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL);
  823.  
  824.         deq_bg_job();
  825.  
  826.         return NOTIFY_DONE;
  827.     }
  828. }
  829.  
  830. /**********************************************************/
  831. void
  832. new_mask_proc()
  833. {
  834.     void add_to_mask_log();
  835.  
  836.     int new, i;
  837.     char filename[MAXPATHLEN];
  838.  
  839.     /* check for max limit of masks */
  840.     if(segal.num_m == MAX_MASKS) {
  841.         vprint"Mask limit (%d) has been reached.  Please remove one first.\n", MAX_MASKS);
  842.         return;
  843.     }
  844.  
  845.     /* setup space for a new mask */
  846.     new = segal.num_m;
  847.     strcpy(m[new].dname, (char *) xv_get(File_pop_new_mask->text_new_dname, PANEL_VALUE, NULL));
  848.     strcpy(m[new].fname, (char *) xv_get(File_pop_new_mask->text_new_fname, PANEL_VALUE, NULL));
  849.     sprintf(filename, "%s/%s", m[new].dname, m[new].fname);
  850.  
  851.     /* no duplicate mask names allowed in log */
  852.     for(i = 0; i < segal.num_m; i++)
  853.         if(strcmp(m[i].fname, m[new].fname) == 0) {
  854.             vprint"The mask %s is already in the Mask Log.\n", m[new].fname);
  855.             return;
  856.         }
  857.  
  858.     /* setup hd info */
  859.     m[new].hd.width = segal.c;
  860.     m[new].hd.height = segal.r;
  861.     m[new].hd.frames = segal.f;
  862.     m[new].hd.o_form = IFMT_BYTE;
  863.     format_init(&m[new].hd, IMAGE_INIT_TYPE, HIPS, -1, *av, "Segal v. 3d");
  864.     (*m[new].hd.std_swif)(FI_INIT_NAME, &m[new].hd, filename, 0);
  865.  
  866.     m[new].hd.data = NULL;
  867.     m[new].loaded = TRUE;
  868.  
  869.     if(new == 0) segal.e_m = 0; 
  870.  
  871.     segal.num_m++;
  872.  
  873.     /* add mask filename to mask log */
  874.     add_to_mask_log(new);
  875.  
  876.     xv_set(File_pop_new_mask->pop_new_mask,
  877.         XV_SHOW, FALSE,
  878.         NULL);
  879. }
  880.  
  881. /**********************************************************/
  882. char
  883. *get_non_comment(fp)
  884. FILE *fp;
  885. {
  886. /* Really useful function for reading in configuration data ... */
  887. /* If the line starts with 2 '**' then it is skipped */
  888.     int comment = FALSE;
  889.     char foo[MAXPATHLEN];
  890.  
  891.     while(fscanf(fp, "%s", foo) != EOF)
  892.         if(strncmp(foo, "**", 2) != 0) {
  893.         /* i.e. Doesn't start w/ '**' */
  894.             if(!comment) return(foo);
  895.         }
  896.         else {
  897.             if(comment == FALSE) comment = TRUE;
  898.             else comment = FALSE;
  899.         }
  900.     return("**EOF");
  901. }
  902.  
  903. /**********************************************/
  904. LOGIC
  905. turn_bit_on_with_log(p)
  906. byte *p;
  907. {
  908.     LOGIC bit_is_excluded();
  909.  
  910.     if(mlog.apply_log
  911.     && bit_is_excluded(*p)) return(FALSE);
  912.  
  913.     TURN_BIT_ON(*p, m[segal.e_m].bit_key)
  914.     return(TRUE);
  915. }
  916.  
  917. /**********************************************/
  918. LOGIC
  919. turn_bit_off_with_log(p)
  920. byte *p;
  921. {
  922.     LOGIC bit_is_included();
  923.  
  924.     if(mlog.apply_log
  925.     && bit_is_included(*p)) return(FALSE);
  926.  
  927.     TURN_BIT_OFF(*p, m[segal.e_m].bit_key)
  928.     return(TRUE);
  929. }
  930.  
  931. /*****************************************/
  932. LOGIC
  933. bit_is_included(p)
  934. byte p;
  935. {
  936.     int i;
  937.  
  938.     For_all_loaded_masks
  939.         if(m[i].mask_type == MASK_INCLUSIVE
  940.         && BIT_IS_ON(p, m[i].bit_key))
  941.             return(TRUE);
  942.     return(FALSE);
  943. }
  944.  
  945. /*****************************************/
  946. LOGIC
  947. bit_is_excluded(p)
  948. byte p;
  949. {
  950.     int i;
  951.  
  952.     For_all_loaded_masks
  953.         if(m[i].mask_type == MASK_EXCLUSIVE
  954.         && BIT_IS_ON(p, m[i].bit_key))
  955.             return(TRUE);
  956.     return(FALSE);
  957. }
  958.  
  959. /*****************************************/
  960. void
  961. store_byte_to_bit(byte_buf, bit_buf, size, mask_num)
  962. byte *byte_buf, *bit_buf;
  963. int size;
  964. int mask_num;
  965. {
  966. /* Packs non-zero bytes to be TRUE bits from the byte buffer to the bit buffer.
  967.  * Size is the length of the byte buffer.
  968.  */
  969.     int i;
  970.  
  971.     for(i = 0; i < size; i++)
  972.         if(byte_buf[i]) {
  973.             /* Turn on the appropriate bit */
  974.             bit_buf[i] = bit_buf[i] | m[mask_num].bit_key;
  975.         }
  976. }
  977.  
  978. /**********************************************/
  979. void
  980. set_frame_slider(win_id)
  981. int win_id;
  982. {
  983.     switch(win_id) {
  984.     case WIN_PAINT :
  985.         xv_set(Paint_win_paint->set_paint_frame,
  986.             PANEL_VALUE, win[grow.swin].f,
  987.             NULL);
  988.         break;
  989.     case WIN_VX :
  990.         xv_set(View_win->set_frame_x,
  991.             PANEL_VALUE, win[grow.swin].f,
  992.             NULL);
  993.         break;
  994.     case WIN_VY :
  995.         xv_set(View_win->set_frame_y,
  996.             PANEL_VALUE, win[grow.swin].f,
  997.             NULL);
  998.         break;
  999.     case WIN_VZ :
  1000.         xv_set(View_win->set_frame_z,
  1001.             PANEL_VALUE, win[grow.swin].f,
  1002.             NULL);
  1003.         break;
  1004.     }
  1005. }
  1006.  
  1007. /*****************************************/
  1008. void
  1009. allocate_buffers()
  1010. {
  1011.     u_char ***alloc_3d_byte_array();
  1012.     u_char **alloc_2d_byte_array();
  1013.     void free_3d_byte_array();
  1014.     void free_2d_byte_array();
  1015.     void build_ximages();
  1016.  
  1017.     int i, cp, largest;
  1018.  
  1019.     if(img.loaded) { /* don't do the first time through */
  1020.         fprintf(stderr, "Freeing buffers for reallocation ...\n");
  1021.  
  1022.         For_rgb if(cbuf[i] != NULL) free_3d_byte_array(cbuf[i]);
  1023.  
  1024.         if(ibuf != NULL) free_3d_byte_array(ibuf);
  1025.         free_3d_byte_array(mbuf);
  1026.  
  1027.         For_all_windows {
  1028.             free_3d_byte_array(win[i].i_data);
  1029.             free_2d_byte_array(win[i].m_data);
  1030.             free_2d_byte_array(win[i].z_data);
  1031.         }
  1032.  
  1033.         For_all_aspects for(cp = 0; cp < NUM_CPLANES; cp++) {
  1034.             free(img.undo[i][cp]);
  1035.             free(img.orig[i][cp]);
  1036.         }
  1037.  
  1038.         free(bm);
  1039.  
  1040.         For_rgb cbuf[i] = NULL;
  1041.  
  1042.         ibuf    = NULL;
  1043.         mbuf    = NULL;
  1044.  
  1045.         For_all_windows {
  1046.             win[i].i_data = NULL;
  1047.             win[i].m_data = NULL;
  1048.             win[i].z_data = NULL;
  1049.         }
  1050.  
  1051.         For_all_aspects for(cp = 0; cp < NUM_CPLANES; cp++) {
  1052.             img.undo[i][cp] = NULL;
  1053.             img.orig[i][cp] = NULL;
  1054.         }
  1055.  
  1056.         bm    = NULL;
  1057.     }
  1058.  
  1059.     if(segal.color) For_rgb
  1060.         cbuf[i] = alloc_3d_byte_array(segal.f, segal.r, segal.c);
  1061.     else ibuf    = alloc_3d_byte_array(segal.f, segal.r, segal.c);
  1062.     mbuf        = alloc_3d_byte_array(segal.f, segal.r, segal.c);
  1063.  
  1064.     For_all_windows {
  1065.         win[i].i_data = alloc_3d_byte_array(NUM_CPLANES,
  1066.             win[i].img_r, win[i].img_c);
  1067.         win[i].m_data = alloc_2d_byte_array(win[i].img_r, win[i].img_c);
  1068.         win[i].z_data = alloc_2d_byte_array(win[i].img_r, win[i].img_c);
  1069.     }
  1070.  
  1071.     For_all_aspects for(cp = 0; cp < NUM_CPLANES; cp++) {
  1072.         img.undo[i][cp] = Calloc(win[i].img_size, byte);
  1073.         img.orig[i][cp] = Calloc(win[i].img_size, byte);
  1074.         if(largest < win[i].img_size) largest = win[i].img_size;
  1075.     }
  1076.  
  1077.     bm = Calloc(largest, byte);
  1078.  
  1079.     /* get rid of now invalid XImages */
  1080.     For_all_windows if(win[i].ximg != NULL) {
  1081.         XDestroyImage(win[i].ximg);
  1082.         win[i].ximg = NULL;
  1083.     }
  1084.             
  1085.     /* create new XImages */
  1086.     build_ximages();
  1087. }
  1088.  
  1089. /***********************************************************/
  1090. void
  1091. realloc_window_buffers(win_id)
  1092. int win_id;
  1093. {
  1094.     u_char **alloc_2d_byte_array();
  1095.     u_char ***alloc_3d_byte_array();
  1096.     void free_2d_byte_array();
  1097.     void free_3d_byte_array();
  1098.  
  1099.     /* realloc buffers */
  1100.     if(win[win_id].i_data != NULL) {
  1101.         free_3d_byte_array(win[win_id].i_data);
  1102.         free_2d_byte_array(win[win_id].m_data);
  1103.         free_2d_byte_array(win[win_id].z_data);
  1104.  
  1105.         win[win_id].i_data = NULL;
  1106.         win[win_id].m_data = NULL;
  1107.         win[win_id].z_data = NULL;
  1108.     }
  1109.  
  1110.     win[win_id].i_data = alloc_3d_byte_array(NUM_CPLANES, win[win_id].img_r, win[win_id].img_c);
  1111.     win[win_id].m_data = alloc_2d_byte_array(win[win_id].img_r, win[win_id].img_c);
  1112.     win[win_id].z_data = alloc_2d_byte_array(win[win_id].img_r, win[win_id].img_c);
  1113. }
  1114.  
  1115. /***********************************************************/
  1116. void
  1117. realloc_window_ximage(win_id)
  1118. int win_id;
  1119. {
  1120.     byte *dbuf;
  1121.  
  1122.     /* realloc ximage */
  1123.     XDestroyImage(win[win_id].ximg);
  1124.     win[win_id].ximg = NULL;
  1125.  
  1126.     dbuf = Calloc(win[win_id].img_size * win[win_id].zoom_mag *
  1127.         win[win_id].zoom_mag, byte);
  1128.     win[win_id].ximg = XCreateImage(display, winv_info->visual, 8,
  1129.         ZPixmap, 0, (char *) dbuf, win[win_id].img_c * 
  1130.         win[win_id].zoom_mag, win[win_id].img_r * win[win_id].zoom_mag,
  1131.         8, 0);
  1132.  
  1133.     if(win[win_id].ximg == NULL) {
  1134.         fprintf(stderr, " Error creating image #%d!\n", win_id);
  1135.         return;
  1136.     }
  1137.     win[win_id].ximg->width = win[win_id].img_c * win[win_id].zoom_mag;    
  1138.     win[win_id].ximg->height = win[win_id].img_r * win[win_id].zoom_mag;    
  1139. }
  1140.  
  1141. /***********************************************************/
  1142. void
  1143. build_ximages()
  1144. {
  1145. /* Instantiates XImages ... call upon loading and upon changing the size of
  1146.  * the 3d data sets.
  1147.  */
  1148.     int i;
  1149.  
  1150.     byte *dbuf;
  1151.  
  1152.     vprint"creating X images ...\n");
  1153.      
  1154.     For_all_windows if (win[i].ximg == NULL) {
  1155.         dbuf = Calloc(win[i].img_size, byte);
  1156.         win[i].ximg = XCreateImage(display, winv_info->visual, 8,
  1157.             ZPixmap, 0, (char *) dbuf, win[i].img_c, win[i].img_r, 
  1158.             8, 0);
  1159.         if (win[i].ximg == NULL) {
  1160.             fprintf(stderr, " Error creating image #%d!\n", i);
  1161.             return;
  1162.         }
  1163.         win[i].ximg->width = win[i].img_c;    
  1164.         win[i].ximg->height = win[i].img_r;    
  1165.     }
  1166. }
  1167.  
  1168. /***********************************************************/
  1169. void
  1170. map_buffers()
  1171. {
  1172. /* Maps the appropriate data from the buffers to be displayed in each of the
  1173.  * windows.  Factors in what is appropriate include whether or not data is
  1174.  * loaded and what options for display have been selected.  Also zooms the
  1175.  * data if the zoom_mag is > 1; otherwise zoom_to_ximage just copies data.
  1176.  */
  1177.     LOGIC okay_to_map();
  1178.     void get_2d_slice();
  1179.     void draw_crop_rectangle();
  1180.     void map_image_to_buf();
  1181.     void map_mask_to_buf();
  1182.     void blend_images_to_buf();
  1183.     void map_nothing_to_buf();
  1184.     void zoom_to_ximage();
  1185.  
  1186.     int i, j, paint_up;
  1187.  
  1188.     vprint"mapping buffers\n");
  1189.  
  1190.     set_watch_cursor();
  1191.  
  1192.     paint_up = xv_get(Paint_win_paint->win_paint, XV_SHOW, NULL);
  1193.  
  1194.     if(img.loaded && segal.disp_image) {
  1195.     if(segal.e_m != UNDEFINED && segal.disp_mask) {
  1196.     /*** both ***/
  1197.     For_all_windows if(win[i].repaint && okay_to_map(win[i].aspect)) {
  1198.         if(segal.color) for(j = 0; j < NUM_CPLANES; j++)
  1199.             get_2d_slice(win[i].aspect, win[i].f, cbuf[j], win[i].i_data[j]);
  1200.         else get_2d_slice(win[i].aspect, win[i].f, ibuf, win[i].i_data[GRAY]);
  1201.         get_2d_slice(win[i].aspect, win[i].f, mbuf, win[i].m_data);
  1202.         blend_images_to_buf(win[i].i_data,
  1203.             win[i].m_data,
  1204.             win[i].z_data,
  1205.             m[segal.e_m].bit_key,
  1206.             win[i].img_r,
  1207.             win[i].img_c,
  1208.             segal.disp_pts);
  1209.         zoom_to_ximage(i);
  1210.         XPutImage(display, win[i].xid, gc, win[i].ximg, 0, 0, 0, 0,
  1211.             win[i].ximg->width, win[i].ximg->height);
  1212.         if(crop.win_id == i) draw_crop_rectangle();
  1213.         win[i].repaint = FALSE;
  1214.     } /* For_all_windows */
  1215.     }
  1216.     else {
  1217.     /*** just image ***/
  1218.     For_all_windows if(win[i].repaint && okay_to_map(win[i].aspect)) {
  1219.         if(segal.color) for(j = 0; j < NUM_CPLANES; j++)
  1220.             get_2d_slice(win[i].aspect, win[i].f, cbuf[j], win[i].i_data[j]);
  1221.         else get_2d_slice(win[i].aspect, win[i].f, ibuf, win[i].i_data[GRAY]);
  1222.         map_image_to_buf(win[i].i_data,
  1223.             win[i].z_data,
  1224.             win[i].img_r,
  1225.             win[i].img_c);
  1226.         zoom_to_ximage(i);
  1227.         XPutImage(display, win[i].xid, gc, win[i].ximg, 0, 0, 0, 0,
  1228.             win[i].ximg->width, win[i].ximg->height);
  1229.         if(crop.win_id == i) draw_crop_rectangle();
  1230.         win[i].repaint = FALSE;
  1231.     } /* For_all_windows */
  1232.     }
  1233.     }
  1234.     else if(segal.e_m != UNDEFINED && segal.disp_mask) {
  1235.     /*** just mask ***/
  1236.     For_all_windows if(win[i].repaint && okay_to_map(win[i].aspect)) {
  1237.         get_2d_slice(win[i].aspect, win[i].f, mbuf, win[i].m_data);
  1238.         map_mask_to_buf(win[i].m_data[0],
  1239.             win[i].z_data[0],
  1240.             m[segal.e_m].bit_key,
  1241.             win[i].img_size,
  1242.             segal.disp_pts);
  1243.         zoom_to_ximage(i);
  1244.         XPutImage(display, win[i].xid, gc, win[i].ximg, 0, 0, 0, 0,
  1245.             win[i].ximg->width, win[i].ximg->height);
  1246.         if(crop.win_id == i) draw_crop_rectangle();
  1247.         win[i].repaint = FALSE;
  1248.     } /* For_all_windows */
  1249.     }
  1250.     else if(!segal.disp_image && !segal.disp_mask && img.loaded) {
  1251.     /*** display nothing ***/
  1252.     For_all_view {
  1253.         map_nothing_to_buf((u_char *) win[i].ximg->data, win[i].img_size);
  1254.         XPutImage(display, win[i].xid, gc, win[i].ximg, 0, 0, 0, 0, win[i].ximg->width, win[i].ximg->height);
  1255.         if(crop.win_id == i) draw_crop_rectangle();
  1256.     } /* i = 0 .. 2 */
  1257.     }
  1258.  
  1259.     if(img.loaded) {
  1260.         if(segal.mode == MODE_REGISTER) {
  1261.         }
  1262.     }
  1263.  
  1264.     unset_watch_cursor();
  1265. }
  1266.  
  1267. /*****************************************/
  1268. LOGIC
  1269. okay_to_map(aspect_id)
  1270. int aspect_id;
  1271. {
  1272.     if(!segal.r3d && (aspect_id == ASPECT_X || aspect_id == ASPECT_Y))
  1273.         return(FALSE);
  1274.     else return(TRUE);
  1275. }
  1276.  
  1277. /*****************************************/
  1278. void
  1279. get_2d_slice(aspect_id, frame, buf_3d, buf_2d)
  1280. int aspect_id, frame;
  1281. u_char ***buf_3d;
  1282. u_char **buf_2d;
  1283. {
  1284.     int z, y;
  1285.  
  1286.     vprint_if"getting 2d slice in:");
  1287.     switch(aspect_id) {
  1288.     case ASPECT_X :
  1289.         if(segal.r3d) {
  1290.             vprint_if" x-aspect\n");
  1291.             for(z = 0; z < segal.f; z++)
  1292.             for(y = 0; y < segal.r; y++)
  1293.                 buf_2d[win[WIN_VX].img_r - 1 - z][y] = buf_3d[z][y][frame];
  1294.         }
  1295.         break;
  1296.     case ASPECT_Y :
  1297.         if(segal.r3d) {
  1298.             vprint_if" y-aspect\n");
  1299.             for(z = 0; z < segal.f; z++)
  1300.                 bcopy(buf_3d[z][segal.r - 1 - frame], buf_2d[win[WIN_VY].img_r- 1 - z], win[WIN_VY].img_c);
  1301.         }
  1302.         break;
  1303.     case ASPECT_Z :
  1304.         vprint_if" z-aspect\n");
  1305.         bcopy(buf_3d[frame][0], buf_2d[0], win[WIN_VZ].img_size);
  1306.         break;
  1307.     default : break;
  1308.     }
  1309. }
  1310.  
  1311. /*****************************************/
  1312. void
  1313. put_2d_slice(aspect_id, frame, buf_3d, buf_2d)
  1314. int aspect_id, frame;
  1315. u_char ***buf_3d;
  1316. u_char **buf_2d;
  1317. {
  1318.     int z, y;
  1319.  
  1320.     if(segal.e_m == UNDEFINED) {
  1321.         vprint"No edit mask to write to!!\n");
  1322.         return;
  1323.     }
  1324.  
  1325.     vprint_if"putting 2d slice in:");
  1326.     switch(aspect_id) {
  1327.     case ASPECT_X :
  1328.         if(segal.r3d) {
  1329.             vprint_if" x-aspect\n");
  1330.             for(z = 0; z < segal.f; z++)
  1331.             for(y = 0; y < segal.r; y++)
  1332.                 buf_3d[z][y][frame] = buf_2d[win[WIN_VX].img_r - 1 - z][y];
  1333.         }
  1334.         break;
  1335.     case ASPECT_Y :
  1336.         if(segal.r3d) {
  1337.             vprint_if" y-aspect\n");
  1338.             for(z = 0; z < segal.f; z++)
  1339.                 bcopy(buf_2d[win[WIN_VY].img_r - 1 - z], buf_3d[z][segal.r - 1 - frame], win[WIN_VY].img_c);
  1340.         }
  1341.         break;
  1342.     case ASPECT_Z :
  1343.         vprint_if" z-aspect\n");
  1344.         bcopy(buf_2d[0], buf_3d[frame][0], (win[WIN_VZ].img_r - 1) * (win[WIN_VZ].img_c - 1));
  1345.         break;
  1346.     default : break;
  1347.     }
  1348. }
  1349.  
  1350. /*****************************************/
  1351. void
  1352. save_image_frame(win_id)
  1353. int win_id;
  1354. {
  1355. /* writes the paint image buffer if necessary to the 3d ibuf */
  1356.     void put_2d_slice();
  1357.  
  1358.     int i;
  1359.  
  1360.     if(img.changed_frame) {
  1361.         set_watch_cursor();
  1362.  
  1363.         if(segal.color) For_rgb
  1364.             put_2d_slice(win[win_id].aspect, win[win_id].f, cbuf[i],
  1365.                 win[win_id].i_data[i]);
  1366.         else put_2d_slice(win[win_id].aspect, win[win_id].f, ibuf,
  1367.             win[win_id].i_data[GRAY]);
  1368.  
  1369.         img.changed_frame = FALSE;
  1370.         img.changed_image = TRUE;
  1371.  
  1372.         unset_watch_cursor();
  1373.     }
  1374. }
  1375.  
  1376. /*****************************************/
  1377. void
  1378. save_image_undo(win_id)
  1379. {
  1380.     int i;
  1381.  
  1382.     set_watch_cursor();
  1383.  
  1384.     if(segal.color) For_rgb bcopy(win[win_id].i_data[i][0],
  1385.         img.undo[win[win_id].aspect][i], win[win_id].img_size);
  1386.     else bcopy(win[win_id].i_data[GRAY][0],
  1387.         img.undo[win[win_id].aspect][GRAY], win[win_id].img_size);
  1388.  
  1389.     unset_watch_cursor();
  1390. }
  1391.  
  1392. /*****************************************/
  1393. void
  1394. save_image_orig(win_id)
  1395. {
  1396.     int i;
  1397.  
  1398.     set_watch_cursor();
  1399.  
  1400.     if(segal.color) For_rgb bcopy(win[win_id].i_data[i][0],
  1401.         img.orig[win[win_id].aspect][i], win[win_id].img_size);
  1402.     else bcopy(win[win_id].i_data[GRAY][0],
  1403.         img.orig[win[win_id].aspect][GRAY], win[win_id].img_size);
  1404.  
  1405.     unset_watch_cursor();
  1406. }
  1407.  
  1408. /*****************************************/
  1409. void
  1410. load_image_undo(win_id)
  1411. {
  1412.     void save_image_frame();
  1413.     void refresh_histogram();
  1414.  
  1415.     int i;
  1416.  
  1417.     set_watch_cursor();
  1418.     
  1419.     if(segal.color) For_rgb bcopy(img.undo[win[win_id].aspect][i],
  1420.         win[win_id].i_data[i][0], win[win_id].img_size);
  1421.     else bcopy(img.undo[win[win_id].aspect][GRAY],
  1422.         win[win_id].i_data[GRAY][0], win[win_id].img_size);
  1423.  
  1424.     img.changed_frame = TRUE;
  1425.     save_image_frame(win_id);
  1426.  
  1427.     if(xv_get(Threshold_pop_threshold->pop_threshold,
  1428.         XV_SHOW, NULL)
  1429.     && (threshold.roi == R2d_WHOLE
  1430.     || threshold.roi == R2d_CROP
  1431.     || threshold.roi == R2d_PT_LIST)) refresh_histogram();
  1432.  
  1433.     unset_watch_cursor();
  1434. }
  1435.  
  1436. /*****************************************/
  1437. void
  1438. load_image_orig(win_id)
  1439. {
  1440.     void save_image_frame();
  1441.     void refresh_histogram();
  1442.  
  1443.     int i;
  1444.  
  1445.     set_watch_cursor();
  1446.     
  1447.     if(segal.color) For_rgb bcopy(img.orig[win[win_id].aspect][i],
  1448.         win[win_id].i_data[i][0], win[win_id].img_size);
  1449.     else bcopy(img.orig[win[win_id].aspect][GRAY],
  1450.         win[win_id].i_data[GRAY][0], win[win_id].img_size);
  1451.  
  1452.     img.changed_frame = TRUE;
  1453.     save_image_frame(win_id);
  1454.  
  1455.     if(xv_get(Threshold_pop_threshold->pop_threshold,
  1456.         XV_SHOW, NULL)
  1457.     && (threshold.roi == R2d_WHOLE
  1458.     || threshold.roi == R2d_CROP
  1459.     || threshold.roi == R2d_PT_LIST)) refresh_histogram();
  1460.  
  1461.     unset_watch_cursor();
  1462. }
  1463.  
  1464. /*****************************************/
  1465. void
  1466. save_mask_frame(win_id)
  1467. int win_id;
  1468. {
  1469. /* writes the paint mask buffer if necessary to the 3d mbuf */
  1470.     void put_2d_slice();
  1471.  
  1472.     if(m[segal.e_m].changed_frame) {
  1473.         put_2d_slice(win[win_id].aspect, win[win_id].f, mbuf,
  1474.             win[win_id].m_data);
  1475.         m[segal.e_m].changed_frame = FALSE;
  1476.         m[segal.e_m].changed_mask = TRUE;
  1477.     }
  1478. }
  1479.  
  1480. /*****************************************/
  1481. void
  1482. save_mask_undo_2d(win_id)
  1483. int win_id;
  1484. {
  1485.     void copy_mask();
  1486.      
  1487.     copy_mask(win[win_id].m_data[0], bm,
  1488.         m[segal.e_m].bit_key, bm_key[win[win_id].aspect],
  1489.         win[win_id].img_size);
  1490. }
  1491.  
  1492. /*****************************************/
  1493. void
  1494. load_mask_undo_2d(win_id)
  1495. int win_id;
  1496. {
  1497.     void copy_mask();
  1498.     void save_mask_frame();
  1499.     void redisplay_all();
  1500.      
  1501.     copy_mask(bm, win[win_id].m_data[0],
  1502.         bm_key[win[win_id].aspect], m[segal.e_m].bit_key,
  1503.         win[win_id].img_size);
  1504.     m[segal.e_m].changed_frame = TRUE;
  1505.     save_mask_frame(win_id);
  1506.     redisplay_all();
  1507. }
  1508.  
  1509. /*****************************************/
  1510. void
  1511. save_mask_undo_3d(mnum)
  1512. int mnum;
  1513. {
  1514. /* Time intensive on large data sets ... use the timer */
  1515.     void copy_mask();
  1516.     LOGIC begin_timer();
  1517.     void set_timer();
  1518.     void end_timer();
  1519.  
  1520.     int f;
  1521.  
  1522.     sprintf(timer.message, "Saving 3d mask to undo buffer");
  1523.     if(!begin_timer())
  1524.         copy_mask(mbuf[0][0], mbuf[0][0], m[mnum].bit_key, m[BUF_UNDO].bit_key, segal.r * segal.c * segal.f);    
  1525.     else {
  1526.         for(f = 0; f < segal.f; f++) {
  1527.             copy_mask(mbuf[f][0], mbuf[f][0], m[mnum].bit_key, m[BUF_UNDO].bit_key, segal.r * segal.c);    
  1528.             set_timer((float) f / (float) segal.f);
  1529.         }
  1530.         end_timer();
  1531.     }
  1532. }
  1533.  
  1534. /*****************************************/
  1535. void
  1536. load_mask_undo_3d(mnum)
  1537. int mnum;
  1538. {
  1539. /* Time intensive on large data sets ... use the timer */
  1540.     void copy_mask();
  1541.     void redisplay_all();
  1542.     LOGIC begin_timer();
  1543.     void set_timer();
  1544.     void end_timer();
  1545.  
  1546.     int f;
  1547.  
  1548.     sprintf(timer.message, "Loading 3d mask from undo buffer");
  1549.     if(!begin_timer())
  1550.         copy_mask(mbuf[0][0], mbuf[0][0], m[BUF_UNDO].bit_key, m[mnum].bit_key, segal.r * segal.c * segal.f);    
  1551.     else {
  1552.         for(f = 0; f < segal.f; f++) {
  1553.             copy_mask(mbuf[f][0], mbuf[f][0], m[BUF_UNDO].bit_key, m[mnum].bit_key, segal.r * segal.c);    
  1554.             set_timer((float) f / (float) segal.f);
  1555.         }
  1556.         end_timer();
  1557.     }
  1558.  
  1559.     redisplay_all();
  1560. }
  1561.  
  1562. /*****************************************/
  1563. void
  1564. copy_mask_info(from_mnum, to_mnum)
  1565. int from_mnum, to_mnum;
  1566. {
  1567.     m[to_mnum].loaded = m[from_mnum].loaded;
  1568.     m[to_mnum].changed_mask = m[from_mnum].changed_mask;
  1569.     m[to_mnum].changed_frame = m[from_mnum].changed_frame;
  1570.     m[to_mnum].mask_type = m[from_mnum].mask_type;
  1571.     m[to_mnum].mask_hue = m[from_mnum].mask_hue;
  1572.  
  1573.     m[to_mnum].hd.name = str_save(m[from_mnum].hd.name);
  1574.  
  1575.     strcpy(m[to_mnum].dname, m[from_mnum].dname);
  1576.     strcpy(m[to_mnum].fname, m[from_mnum].fname);
  1577. }
  1578.  
  1579. /*****************************************/
  1580. void
  1581. copy_mask(from_buf, to_buf, from_key, to_key, size)
  1582. byte *from_buf, *to_buf, from_key, to_key;
  1583. int size;
  1584. {
  1585.     int i;
  1586.  
  1587.     set_watch_cursor();
  1588.  
  1589.     for(i = 0; i < size; i++)
  1590.         if(BIT_IS_ON(from_buf[i], from_key))
  1591.             TURN_BIT_ON(to_buf[i], to_key)
  1592.         else TURN_BIT_OFF(to_buf[i], to_key)
  1593.  
  1594.     unset_watch_cursor();
  1595. }
  1596.  
  1597. /*****************************************/
  1598. void
  1599. fill_mask(roi, win_id, mcolor)
  1600. int roi, win_id, mcolor;    
  1601. {
  1602.     void save_mask_frame();
  1603.     void redisplay_all();
  1604.  
  1605.     int i, size;
  1606.     byte *mdata;
  1607.  
  1608.     if(roi == R2d_WHOLE) {
  1609.         size = win[win_id].img_size;
  1610.         mdata = win[win_id].m_data[0];
  1611.     }
  1612.     else {
  1613.         size = segal.r * segal.c * segal.f;
  1614.         mdata = mbuf[0][0];
  1615.     }
  1616.  
  1617.     if(mcolor == BLACK)
  1618.         for(i = 0; i < size; i++)
  1619.             TURN_BIT_OFF(mdata[i], m[segal.e_m].bit_key)
  1620.     else if(mcolor == WHITE)
  1621.         for(i = 0; i < size; i++)
  1622.             TURN_BIT_ON(mdata[i], m[segal.e_m].bit_key)
  1623.     else if(mcolor == INVERT)
  1624.         for(i = 0; i < size; i++) {
  1625.             if(BIT_IS_ON(mdata[i], m[segal.e_m].bit_key))
  1626.                 TURN_BIT_OFF(mdata[i], m[segal.e_m].bit_key)
  1627.             else TURN_BIT_ON(mdata[i], m[segal.e_m].bit_key)
  1628.         }
  1629.  
  1630.     if(roi == R2d_WHOLE) {
  1631.         m[segal.e_m].changed_frame = TRUE;
  1632.         save_mask_frame(win_id);
  1633.     }
  1634.     redisplay_all();
  1635. }
  1636.  
  1637. /*****************************************/
  1638. void
  1639. update_bytes_required()
  1640. {
  1641.     char foo[80];
  1642.     int col_multiplier;
  1643.     float megs;
  1644.  
  1645.     segal.r = segal.r2 - segal.r1 + 1;
  1646.     segal.c = segal.c2 - segal.c1 + 1;
  1647.     segal.f = segal.f2 - segal.f1 + 1;
  1648.  
  1649. /* size of the binary for "segal" */
  1650. #define seg_size 2.6
  1651.  
  1652.     if(segal.color) col_multiplier = 3 + 1; /* 3 planes + 1 mask */
  1653.     else col_multiplier = 1 + 1;
  1654.  
  1655.     megs = seg_size
  1656.         + (float) ((segal.r * segal.c * segal.f) * col_multiplier)
  1657.         / 1000000.;
  1658.  
  1659. #undef seg_size
  1660.  
  1661.     sprintf(foo, "Bytes required: %3.1fM", megs);
  1662.     xv_set(File_pop_load_image->msg_bytes_required,
  1663.         PANEL_LABEL_STRING, foo,
  1664.         NULL);
  1665.  
  1666.     if(segal.f > 1) {
  1667.     /* setup for 3d */
  1668.         segal.r3d = TRUE;
  1669.         segal.disp_xy = TRUE;
  1670.         xv_set(Paint_win_paint->set_aspect,
  1671.             PANEL_INACTIVE, FALSE,
  1672.             NULL);
  1673.     }
  1674.     else {
  1675.     /* setup for 2d */
  1676.         segal.r3d = FALSE;
  1677.         segal.disp_xy = FALSE;
  1678.         xv_set(Paint_win_paint->set_aspect,
  1679.             PANEL_INACTIVE, TRUE,
  1680.             NULL);
  1681.         win[WIN_PAINT].aspect = ASPECT_Z;
  1682.     }
  1683. }
  1684.  
  1685. /*****************************************/
  1686. void
  1687. init_info_from_header()
  1688. {
  1689.     int i;
  1690.  
  1691.     img.r = segal.r = img.hd.height;
  1692.     img.c = segal.c = img.hd.width;
  1693.     img.f = segal.f = img.hd.frames;
  1694.     img.frame_size = img.r * img.c;
  1695.  
  1696.     segal.r1 = 0;
  1697.     segal.r2 = img.r - 1;
  1698.     segal.c1 = 0;
  1699.     segal.c2 = img.c - 1;
  1700.     segal.f1 = 0;
  1701.     segal.f2 = img.f - 1;
  1702.  
  1703.     if(segal.f > 1) {
  1704.     /* setup for 3d */
  1705.         segal.r3d = TRUE;
  1706.         segal.disp_xy = TRUE;
  1707.         xv_set(Paint_win_paint->set_aspect,
  1708.             PANEL_INACTIVE, FALSE,
  1709.             NULL);
  1710.     }
  1711.     else {
  1712.     /* setup for 2d */
  1713.         segal.r3d = FALSE;
  1714.         segal.disp_xy = FALSE;
  1715.         xv_set(Paint_win_paint->set_aspect,
  1716.             PANEL_INACTIVE, TRUE,
  1717.             NULL);
  1718.         win[WIN_PAINT].aspect = ASPECT_Z;
  1719.     }
  1720.  
  1721.     /* should always be either 0 (gray) or 3 (sep color planes) */
  1722.     img.color = segal.color = isColorImage(img.hd.in_color);
  1723.  
  1724.     img.changed_image = FALSE;
  1725.  
  1726.     For_all_windows {
  1727.         win[i].zoom_mag = 1;
  1728.         win[i].f = 0;
  1729.     }
  1730. }
  1731.  
  1732. void
  1733. init_info_from_loading()
  1734. {
  1735.     int i;
  1736.  
  1737.     win[WIN_VX].img_r = segal.f;
  1738.     win[WIN_VX].img_c = segal.r;
  1739.  
  1740.     win[WIN_VY].img_r = segal.f;
  1741.     win[WIN_VY].img_c = segal.c;
  1742.  
  1743.     win[WIN_VZ].img_r = segal.r;
  1744.     win[WIN_VZ].img_c = segal.c;
  1745.  
  1746.     /* paint and ref_frame windows start out in the z-aspect */
  1747.     win[WIN_PAINT].aspect = ASPECT_Z;
  1748.     win[WIN_PAINT].img_r = segal.r;
  1749.     win[WIN_PAINT].img_c = segal.c;
  1750.  
  1751.     win[WIN_REF].aspect = ASPECT_Z;
  1752.     win[WIN_REF].img_r = segal.r;
  1753.     win[WIN_REF].img_c = segal.c;
  1754.  
  1755.     For_all_windows win[i].img_size = win[i].img_r * win[i].img_c;
  1756. }
  1757.  
  1758.